using Microsoft.EntityFrameworkCore.Diagnostics;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using way.controller;
using way.model;
using way.util;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;

namespace way.view
{
    public partial class MenuInCoreView : Form
    {
        WinformUtil winformUtil = InstanceManage.getWinformUtil();
        MenuController controller = InstanceManage.getMenuController();
        MenuCore menuCore = InstanceManage.getMenuCore();
        List<MenuInCoreEntity> menuInCores = new List<MenuInCoreEntity>();
        MenuInCoreEntity selectMenuInCoreEntity;

        //
        public int id = 0;
        public int menuId = 0;
        public string table = string.Empty;
        public MenuInCoreView()
        {
            InitializeComponent();
            initCompoent();
            initPageLocation();
            initMethod();
        }
        private void initCompoent()
        {
            this.KeyPreview = true;
            //this.KeyDown += new KeyEventHandler(MenuView_KeyDown);
        }
        public void initMethod()
        {
            string method = "addData,queryData,updateData,deleteData," +
                "changeBefore,changeAfter,addBefore,addAfter";
            comboBoxMethod.Items.AddRange(method.Split(','));
        }
        private void initPageLocation()
        {
            int ScreenWidth = Screen.PrimaryScreen.WorkingArea.Width;
            int ScreenHeight = Screen.PrimaryScreen.WorkingArea.Height;
            //int x = (int)ScreenWidth/3*2 - (int)this.Width/2 - 5;
            int x = (ScreenWidth - this.Width) / 10 * 1 - 5;
            int y = ScreenHeight - this.Height - 5;
            this.Location = new Point(x, y);
        }
        public void LoadData(MenuEntity menu)
        {
            textBoxMenuInfomation.Text = $"{menu.id}, {menu.level}, {menu.sort}, {menu.create}, {menu.update}";
            textBoxMenuName.Text = menu.name;
            menuId = menu.id;
            table = menu.table + menuCore.inCore;
            queryData();
            initContext();
        }
        public void initContext()
        {
            richTextBoxContext.Clear();
            foreach (var item in menuInCores)
            {
                winformUtil.loadContext(item.attribute+ "\r\n", Color.White, richTextBoxContext);
                winformUtil.loadContext("        " + item.context+ "\r\n\r\n", Color.Lime, richTextBoxContext);
            }
        }
        public void initTreeView()
        {
            treeViewMethod.Nodes.Clear();
            treeViewMethod.BeginUpdate();
            for (int i = 0; i < menuInCores.Count; i++)
            {
                MenuInCoreEntity inCore = menuInCores[i];
                TreeNode nodeHead = new TreeNode
                {
                    Name = Convert.ToString(inCore.id),
                    Text = inCore.attribute,
                    Tag = inCore
                };
                treeViewMethod.Nodes.Add(nodeHead);
            }
            treeViewMethod.EndUpdate();
            treeViewMethod.ExpandAll();
        }
        #region service
        public void queryData()
        {
            Result<List<MenuInCoreEntity>> res = new Result<List<MenuInCoreEntity>> { table = table };
            controller.queryMenuInCoreByMenuId(menuId, res);
            if (res.check()) { messageShow(res); return; }
            menuInCores = res.data;
            initTreeView();
            messageShow(res);
        }
        public void addData()
        {
            Result<MenuInCoreEntity> res = new() { table = table };
            MenuInCoreEntity menuInCoreEntity = new()
            {
                menuId = menuId,
                attribute = textBoxNewAttribute.Text,
                context = richTextBoxContext.Text
            };
            res.data = menuInCoreEntity;
            controller.AddMenuInCoreByMenuId(res);
            if (res.check()) { messageShow(res); return; }
            queryData();
            messageShow(res);
        }
        public void updateData()
        {
            Result<MenuInCoreEntity> res = new() { table = table };
            MenuInCoreEntity updateEntity = new()
            {
                id =selectMenuInCoreEntity.id,
                attribute =textBoxNewAttribute.Text,
                context =richTextBoxContext.Text,
            };
            res.data = updateEntity;
            controller.updateMenuInCoreById(res);
            if (res.check()) { messageShow(res); return; }
            queryData();
            messageShow(res);
        }
        //
        public void changeBefore()
        {
            Result<int> res = new() { table = table };
            string str = textBoxChangeId.Text;
            if (string.IsNullOrWhiteSpace(str))
            {
                res.setStatus(ResultCode.dataNull);
                messageShow(res);
                return;
            }
            str = str.Substring(0, str.IndexOf('='));
            string str1 = textBoxTargetId.Text;
            if (string.IsNullOrWhiteSpace(str1))
            {
                res.setStatus(ResultCode.dataNull);
                messageShow(res);
                return;
            }
            str1 = str1.Substring(0, str1.IndexOf('='));
            int i = Convert.ToInt32(str);
            int i1 = Convert.ToInt32(str1);
            controller.changeBeforeInCore(i, i1, res);
            queryData();
            messageShow(res);
        }
        public void changeAfter()
        {
            Result<int> res = new() { table = table };
            string str = textBoxChangeId.Text;
            if (string.IsNullOrWhiteSpace(str))
            {
                res.setStatus(ResultCode.dataNull);
                messageShow(res);
                return;
            }
            str = str.Substring(0, str.IndexOf('='));
            string str1 = textBoxTargetId.Text;
            if (string.IsNullOrWhiteSpace(str1))
            {
                res.setStatus(ResultCode.dataNull);
                messageShow(res);
            }
            str1 = str1.Substring(0, str1.IndexOf('='));
            int i = Convert.ToInt32(str);
            int i1 = Convert.ToInt32(str1);
            controller.changeAfterInCore(i, i1, res);
            queryData();
            messageShow(res);
        }
        public void addBefore()
        {
            Result<int> res = new() { table = table };
            //string str = textBoxChangeId.Text;
            //if (string.IsNullOrWhiteSpace(str))
            //{
            //    res.setStatus(ResultCode.dataNull);
            //    messageShow(res);
            //}
            //str = str.Substring(0, str.IndexOf('='));
            string str1 = textBoxTargetId.Text;
            if (string.IsNullOrWhiteSpace(str1))
            {
                res.setStatus(ResultCode.dataNull);
                messageShow(res);
                return;
            }
            str1 = str1.Substring(0, str1.IndexOf('='));
            //int i = Convert.ToInt32(str);
            int i1 = Convert.ToInt32(str1);
            MenuInCoreEntity entity = new()
            {
                context = richTextBoxContext.Text,
                attribute = textBoxNewAttribute.Text
            };
            controller.addBeforeInCore(entity, i1, res);
            queryData();
            messageShow(res);
        }
        public void addAfter()
        {
            Result<int> res = new() { table = table };
            //string str = textBoxChangeId.Text;
            //if (string.IsNullOrWhiteSpace(str))
            //{
            //    res.setStatus(ResultCode.dataNull);
            //    messageShow(res);
            //}
            //str = str.Substring(0, str.IndexOf('='));
            string str1 = textBoxTargetId.Text;
            if (string.IsNullOrWhiteSpace(str1))
            {
                res.setStatus(ResultCode.dataNull);
                messageShow(res);
                return;
            }
            str1 = str1.Substring(0, str1.IndexOf('='));
            //int i = Convert.ToInt32(str);
            int i1 = Convert.ToInt32(str1);
            MenuInCoreEntity entity = new()
            {
                context = richTextBoxContext.Text,
                attribute = textBoxNewAttribute.Text
            };
            controller.addAfterInCore(entity, i1, res);
            queryData();
            messageShow(res);
        }
        public void deleteData()
        {
            Result<MenuInCoreEntity> res = new() { table = table };
            MenuInCoreEntity updateEntity = new()
            {
                id=selectMenuInCoreEntity.id,
            };
            res.data = updateEntity;
            controller.deleteMenuInCoreById(res);
            if (res.check()) { messageShow(res); return; }
            queryData();
            messageShow(res);
        }
        //
        public void MethodMenu(string name)
        {
            callMethodByString(name);
            //switch (name)
            //{
            //    case "queryMenu":
            //        queryMenu();
            //        break;
            //}
        }
        private void callMethodByString(string methodName, params object[] parameters)
        {
            if (string.IsNullOrEmpty(methodName)) { messageShow(ResultCode.methodNotFound + methodName, Color.Red); return; }
            try
            {
                Type formType = this.GetType();
                MethodInfo method = formType.GetMethod(methodName, parameters.Select(p => p?.GetType() ?? typeof(object)).ToArray());
                if (method == null)
                {
                    messageShow(ResultCode.methodNotFound + methodName, Color.Red);
                    return;
                }
                method.Invoke(this, parameters);
            }
            catch (Exception ex)
            {
                messageShow(ResultCode.methodNotFound + methodName + ex.Message, Color.Red);
            }
        }
        #endregion
        #region messageShow
        public Result<T> messageShow<T>(Result<T> result)
        {
            winformUtil.messageShow(result, richTextBoxMessage);
            return result;
        }
        public void messageShow(string message, Color status)
        {
            winformUtil.messageShow(message, status, richTextBoxMessage);
        }
        public void messageShow(ResultCode code)
        {
            winformUtil.messageShow(code, richTextBoxMessage);
        }
        #endregion
        #region handle
        private void MenuInCoreView_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                MethodMenu(comboBoxMethod.Text);
                return;
            }
            if (e.Alt && e.KeyCode == Keys.D1)
            {
                textBoxChangeId.Text = selectMenuInCoreEntity.id + "=" + selectMenuInCoreEntity.attribute;
                return;
            }
            if (e.Alt && e.KeyCode == Keys.D2)
            {
                textBoxTargetId.Text = selectMenuInCoreEntity.id + "=" + selectMenuInCoreEntity.attribute;
                return;
            }
            if (e.Alt && e.KeyCode == Keys.U)
            {
                comboBoxMethod.Text = "updateData";
                return;
            }
            if (e.Alt && e.KeyCode == Keys.D)
            {
                comboBoxMethod.Text = "deleteData";
                return;
            }
        }
        private void treeViewMethod_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            selectMenuInCoreEntity = (MenuInCoreEntity)e.Node.Tag;
            textBoxName.Text = selectMenuInCoreEntity.attribute;
            richTextBoxContext.Text = selectMenuInCoreEntity.context;
        }
        
        private void textBoxNewAttribute_KeyPress(object sender, KeyPressEventArgs e)
        {
            //if (e.KeyChar == (char)Keys.Enter) {
            //    MethodMenu(comboBoxMethod.Text);
            //}
        }
        private void textBoxMenuName_MouseClick(object sender, MouseEventArgs e)
        {
            initContext();
        }
        #endregion
    }
}
